import type { Context } from 'elysia';
import bcrypt from 'bcrypt';
import { eq } from 'drizzle-orm';
import { db } from '../db';
import { users } from '../db/schema';
import { generateToken, generateRefreshToken, generateTokenWithExpiry, verifyToken, extractTokenFromHeader } from '../utils/jwt';
import type { JWTPayload } from '../utils/jwt';
import { nanoid } from 'nanoid';
import { successResponse, errorResponse, ApiError, asyncHandler, Logger } from '../utils/response';
import { logUserOperation, logAuthOperation } from '../utils/systemLogger';

// 创建默认管理员用户（如果不存在）
async function createDefaultAdmin() {
  try {
    const existingAdmin = await db.select().from(users).where(eq(users.username, 'admin')).limit(1);
    
    if (existingAdmin.length === 0) {
      const hashedPassword = await bcrypt.hash('admin123', 10);
      await db.insert(users).values({
        id: nanoid(),
        username: 'admin',
        password: hashedPassword,
        email: 'admin@cx-ad.com',
        role: 'admin',
        status: 'active',
        avatar: '/public/default-avatar.png'
      });
      Logger.info('Default admin user created: admin/admin123');
    }
  } catch (error) {
    Logger.error('Error creating default admin', { error: error.message });
  }
}

// 初始化时创建默认管理员
createDefaultAdmin();

// 模拟用户数据（保留用于向后兼容）
const mockUsers = [
  {
    id: '1',
    username: 'admin',
    password: '$2b$10$rQZ9QmjkQZ9QmjkQZ9QmjkQZ9QmjkQZ9QmjkQZ9QmjkQZ9QmjkQZ9Q', // 'admin123'
    role: 'admin',
    name: '管理员'
  }
];

export interface LoginRequest {
  username: string;
  password: string;
}

export interface RegisterRequest {
  username: string;
  password: string;
  email: string;
  name: string;
}

/**
 * 用户登录
 */
export const login = asyncHandler(async ({ body }: Context) => {
  const { username, password, remember } = body as LoginRequest;
  
  if (!username || !password) {
    throw ApiError.validation('用户名和密码不能为空');
  }
  
  // 查找用户
  const userResult = await db.select().from(users).where(eq(users.username, username)).limit(1);
  const user = userResult[0];
  
  if (!user || user.status !== 'active') {
    throw ApiError.unauthorized('用户名或密码错误');
  }
  
  // 验证密码
  const isValidPassword = await bcrypt.compare(password, user.password);
  if (!isValidPassword) {
    throw ApiError.unauthorized('用户名或密码错误');
  }
  
  // 生成JWT令牌
  const payload: JWTPayload = {
    userId: user.id,
    username: user.username,
    role: user.role
  };
  
  // 根据是否记住密码设置不同的过期时间
  const token = generateTokenWithExpiry(payload, remember);
  const refreshToken = generateRefreshToken(payload);
  
  const expiryInfo = remember ? '3天' : '1天';
  // 记录登录日志
  await logAuthOperation(
    user.id,
    user.username,
    'login',
    `用户登录: ${user.username}`,
    { role: user.role, remember: remember || false, tokenExpiry: expiryInfo }
  );

  Logger.info('User login successful', { 
    username: user.username, 
    role: user.role, 
    remember: remember || false,
    tokenExpiry: expiryInfo
  });
  
  return successResponse({
    token,
    refreshToken,
    user: {
      id: user.id,
      username: user.username,
      email: user.email,
      role: user.role
    },
    tokenExpiry: expiryInfo
  }, '登录成功');
});

/**
 * 用户注册
 */
export const register = asyncHandler(async ({ body }: Context) => {
  const { username, password, email } = body as RegisterRequest;
  
  if (!username || !password || !email) {
    throw ApiError.validation('用户名、密码和邮箱不能为空');
  }
  
  // 检查用户名是否已存在
  const existingUserByUsername = await db.select().from(users).where(eq(users.username, username)).limit(1);
  
  if (existingUserByUsername.length > 0) {
    throw ApiError.conflict('用户名已存在');
  }
  
  // 加密密码
  const hashedPassword = await bcrypt.hash(password, 10);
  
  // 创建新用户
  const newUserData = {
    id: nanoid(),
    username,
    password: hashedPassword,
    email,
    role: 'guest',
    status: 'active',
    avatar: '/public/default-avatar.png'
  };
  
  const [newUser] = await db.insert(users).values(newUserData).returning();
  
  // 记录注册日志
  await logAuthOperation(
    newUser?.id || '',
    username,
    'register',
    `用户注册: ${username} (${email})`,
    { role: 'guest' }
  );
  
  Logger.info('User registered successfully', { username });
  
  return successResponse({
    user: {
      id: newUser?.id || '',
      username: newUser?.username || '',
      email: newUser?.email || '',
      role: newUser?.role || 'guest'
    }
  }, '注册成功');
});

/**
 * 获取当前用户信息
 */
export const getCurrentUser = asyncHandler(async ({ user }: any) => {
  if (!user) {
    throw ApiError.unauthorized('未认证');
  }
  
  // user 就是 JWT payload，直接使用 user.userId
  const userResult = await db.select().from(users).where(eq(users.id, user.userId)).limit(1);
  const currentUser = userResult[0];
  
  if (!currentUser || currentUser.status !== 'active') {
    throw ApiError.notFound('用户不存在或已被禁用');
  }
  
  Logger.info('Current user info retrieved', { userId: currentUser.id, username: currentUser.username });
  
  return successResponse({
    id: currentUser.id,
    username: currentUser.username,
    email: currentUser.email,
    role: currentUser.role
  });
});

/**
 * 修改密码
 */
export const changePassword = asyncHandler(async ({ body, user }: any) => {
  const { oldPassword, newPassword } = body;
  
  if (!oldPassword || !newPassword) {
    throw ApiError.validation('旧密码和新密码不能为空');
  }
  
  const userResult = await db.select().from(users).where(eq(users.id, user.userId)).limit(1);
  const currentUser = userResult[0];
  
  if (!currentUser || currentUser.status !== 'active') {
    throw ApiError.notFound('用户不存在');
  }
  
  // 验证旧密码
  const isValidOldPassword = await bcrypt.compare(oldPassword, currentUser.password);
  if (!isValidOldPassword) {
    throw ApiError.validation('旧密码错误');
  }
  
  // 加密新密码
  const hashedNewPassword = await bcrypt.hash(newPassword, 10);
  await db.update(users).set({ password: hashedNewPassword }).where(eq(users.id, user.userId));
  
  // 记录密码修改日志
  await logAuthOperation(
    user.userId,
    currentUser.username,
    'change_password',
    `用户修改密码: ${currentUser.username}`
  );
  
  Logger.info('Password changed successfully', { userId: user.userId, username: currentUser.username });
  
  return successResponse(null, '密码修改成功');
});

/**
 * 刷新令牌
 */
export const refreshToken = asyncHandler(async ({ headers }: Context) => {
  const token = extractTokenFromHeader(headers.authorization);
  
  if (!token) {
    throw ApiError.unauthorized('缺少刷新令牌');
  }
  
  // 验证刷新令牌
  const payload = verifyToken(token);
  
  if (!payload) {
    throw ApiError.unauthorized('无效的刷新令牌');
  }
  
  // 检查用户是否仍然存在且活跃
  const userResult = await db.select().from(users).where(eq(users.id, payload.userId)).limit(1);
  const user = userResult[0];
  
  if (!user || user.status !== 'active') {
    throw ApiError.unauthorized('用户不存在或已被禁用');
  }
  
  // 生成新的访问令牌和刷新令牌
  const newPayload: JWTPayload = {
    userId: user.id,
    username: user.username,
    role: user.role
  };
  
  const newToken = generateToken(newPayload);
  const newRefreshToken = generateRefreshToken(newPayload);
  
  Logger.info('Token refreshed successfully', { userId: user.id, username: user.username });
  
  return successResponse({
    token: newToken,
    refreshToken: newRefreshToken,
    user: {
      id: user.id,
      username: user.username,
      email: user.email,
      role: user.role
    }
  }, '令牌刷新成功');
});

/**
 * 用户登出
 */
export const logout = asyncHandler(async ({ user }: any) => {
  if (!user) {
    throw ApiError.unauthorized('未认证');
  }
  
  // 记录登出日志
  await logAuthOperation(
    user.userId,
    user.username,
    'logout',
    `用户登出: ${user.username}`
  );
  
  Logger.info('User logout successful', { userId: user.userId, username: user.username });
  
  return successResponse(null, '退出成功');
});